package com.eas.biz.service.exam.impl;

import java.util.LinkedList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.eas.biz.constants.BizConstants;
import com.eas.biz.dao.exam.dataobject.ExamDO;
import com.eas.biz.dao.exam.dataobject.ExamQuery;
import com.eas.biz.dao.exam.interfaces.ExamDao;
import com.eas.biz.dao.examDetail.dataobject.ExamDetailDO;
import com.eas.biz.dao.examDetail.dataobject.ExamDetailQuery;
import com.eas.biz.dao.examDetail.interfaces.ExamDetailDao;
import com.eas.biz.service.exam.domain.Exam;
import com.eas.biz.service.exam.domain.ExamQuestionDetail;
import com.eas.biz.service.exam.domain.ExamSubjectDetail;
import com.eas.biz.service.exam.interfaces.ExamService;

@Service("examService")
public class ExamServiceImpl implements ExamService {

    @Autowired
    private ExamDao examDao;

    @Autowired
    private ExamDetailDao examDetailDao;

    public List<Exam> getAllExam() {
        ExamQuery query = new ExamQuery();
        List<ExamDO> list = examDao.selectByQuery(query);
        List<Exam> result = new LinkedList<Exam>();
        for (ExamDO examDO : list) {
            Exam exam = new Exam();
            fillExam(exam, examDO);
            result.add(exam);
        }
        return result;
    }

    public Exam getSimpleExam(long examId) {
        return buildExamBody(examId);
    }

    public Exam getExamDetail(long examId) {
        Exam exam = buildExamBody(examId);

        if (exam != null) {
            for (String subject : exam.getSubjectDetailMap().keySet()) {
                ExamSubjectDetail subjectDetail = buildSubjectDetail(examId, subject);
                if (subjectDetail != null) {
                    subjectDetail.setExam(exam);
                    exam.addSubjectDetail(subjectDetail);
                }
            }

        }
        return exam;
    }

    public ExamSubjectDetail getExamSubjectDetail(long examId, String subject) {
        return buildSubjectDetail(examId, subject);
    }

    public ExamQuestionDetail getExamQuestionDetail(long examId, String subject,
            String questionNumber) {
        ExamDetailQuery query = new ExamDetailQuery();
        query.setExamId(examId);
        query.setSubject(subject);
        query.setQuestionNumber(questionNumber);
        List<ExamDetailDO> details = examDetailDao.selectByQuery(query);

        if (details.size() > 0) {
            ExamDetailDO detailDO = details.get(0);
            ExamQuestionDetail detail = new ExamQuestionDetail();
            fillQuestionDetail(detailDO, detail);
            return detail;
        } else {
            return null;
        }
    }

    private Exam buildExamBody(long examId) {
        ExamDO examDO = examDao.selectById(examId);
        if (examDO == null) {
            return null;
        }

        Exam exam = new Exam();
        fillExam(exam, examDO);
        return exam;
    }

    private ExamSubjectDetail buildSubjectDetail(long examId, String subject) {
        ExamDetailQuery query = new ExamDetailQuery();
        query.setExamId(examId);
        query.setSubject(subject);
        List<ExamDetailDO> details = examDetailDao.selectByQuery(query);

        if (details.size() > 0) {
            ExamSubjectDetail detail = new ExamSubjectDetail();
            fillSubjectDetail(details.get(0), detail);

            for (ExamDetailDO detailDO : details) {
                ExamQuestionDetail questionDetail = new ExamQuestionDetail();
                fillQuestionDetail(detailDO, questionDetail);
                detail.addQuestionDetail(questionDetail);
                questionDetail.setSubjectDetail(detail);
            }

            return detail;
        } else {
            return null;
        }
    }

    private void fillSubjectDetail(ExamDetailDO detailDO, ExamSubjectDetail detail) {
        detail.setSubject(detailDO.getSubject());
        detail.setQuestionCount(detailDO.getQuestionCount());
        detail.setTotalScore(detailDO.getQuestionCount());
    }

    private void fillQuestionDetail(ExamDetailDO detailDO, ExamQuestionDetail detail) {
        detail.setQuestionNumber(detailDO.getQuestionNumber());
        detail.setQuestionType(detailDO.getQuestionType());
        detail.setObjective(detailDO.getIsObjective() != null && 1 == detailDO.getIsObjective());
        detail.setPrimaryTag(detailDO.getPrimaryTag());
        detail.setScore(detailDO.getScore());
        detail.setAnswer(detailDO.getAnswer());
        detail.addTags(detailDO.getTags());
    }

    private void fillExam(Exam exam, ExamDO examDO) {
        exam.setId(examDO.getId());
        exam.setTitle(examDO.getTitle());
        exam.setDirector(examDO.getDirector());
        exam.setDescription(examDO.getDescription());
        exam.setTimeStart(examDO.getTimeStart());
        exam.setTimeEnd(examDO.getTimeEnd());
        if (StringUtils.isNotBlank(examDO.getSubjects())) {
            String[] subjects = StringUtils.split(examDO.getSubjects(),
                    BizConstants.FIELD_VALUE_SPERATER);
            for (String subject : subjects) {
                exam.getSubjectDetailMap().put(subject, null);
                exam.getSubjectList().add(subject);
            }
        }
        if (StringUtils.isNotBlank(examDO.getAreaIds())) {
            String[] ids = StringUtils
                    .split(examDO.getAreaIds(), BizConstants.FIELD_VALUE_SPERATER);
            for (String id : ids) {
                if (StringUtils.isNumeric(id)) {
                    exam.getAreaIdList().add(Long.valueOf(id));
                }
            }
        }
    }

}
